package com.ruoyi.veterinary.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.veterinary.domain.VetBillDetail;
import com.ruoyi.veterinary.mapper.VetBillDetailMapper;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.veterinary.mapper.VetBillMapper;
import com.ruoyi.veterinary.mapper.VetOutboundMapper;
import com.ruoyi.veterinary.domain.VetBill;
import com.ruoyi.veterinary.domain.VetOutbound;
import com.ruoyi.veterinary.service.IVetBillService;
import com.ruoyi.common.exception.ServiceException;

/**
 * 账单管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-19
 */
@Service
public class VetBillServiceImpl implements IVetBillService 
{
    @Autowired
    private VetBillMapper vetBillMapper;
    
    @Autowired
    private VetOutboundMapper vetOutboundMapper;

    /**
     * 查询账单管理
     * 
     * @param billId 账单管理主键
     * @return 账单管理
     */
    @Autowired
    private VetBillDetailMapper vetBillDetailMapper;

    @Override
    public VetBill selectVetBillByBillId(Long billId)
    {
        VetBill vetBill = vetBillMapper.selectVetBillByBillId(billId);
        if (vetBill != null) {
            // 查询账单明细列表
            List<VetBillDetail> billDetailList = vetBillDetailMapper.selectVetBillDetailByBillId(billId);
            vetBill.setBillDetailList(billDetailList);
        }
        return vetBill;
    }

    /**
     * 查询账单管理列表
     * 
     * @param vetBill 账单管理
     * @return 账单管理
     */
    @Override
    public List<VetBill> selectVetBillList(VetBill vetBill)
    {
        return vetBillMapper.selectVetBillList(vetBill);
    }

    /**
     * 新增账单管理
     * 
     * @param vetBill 账单管理
     * @return 结果
     */
    @Override
    public int insertVetBill(VetBill vetBill)
    {
        // 生成账单编号
        if (vetBill.getBillNo() == null || vetBill.getBillNo().isEmpty()) {
            vetBill.setBillNo(generateBillNo());
        }
        
        // 计算未付金额
        if (vetBill.getTotalAmount() != null && vetBill.getPaidAmount() != null) {
            vetBill.setUnpaidAmount(vetBill.getTotalAmount().subtract(vetBill.getPaidAmount()));
        }
        
        // 设置支付状态
        updatePaymentStatusByAmount(vetBill);
        
        vetBill.setCreateTime(DateUtils.getNowDate());
        return vetBillMapper.insertVetBill(vetBill);
    }

    /**
     * 修改账单管理
     * 
     * @param vetBill 账单管理
     * @return 结果
     */
    @Override
    public int updateVetBill(VetBill vetBill)
    {
        // 重新计算未付金额
        if (vetBill.getTotalAmount() != null && vetBill.getPaidAmount() != null) {
            vetBill.setUnpaidAmount(vetBill.getTotalAmount().subtract(vetBill.getPaidAmount()));
        }
        
        // 更新支付状态
        updatePaymentStatusByAmount(vetBill);
        
        vetBill.setUpdateTime(DateUtils.getNowDate());
        return vetBillMapper.updateVetBill(vetBill);
    }

    /**
     * 批量删除账单管理
     * 
     * @param billIds 需要删除的账单管理主键
     * @return 结果
     */
    @Override
    public int deleteVetBillByBillIds(Long[] billIds)
    {
        return vetBillMapper.deleteVetBillByBillIds(billIds);
    }

    /**
     * 删除账单管理信息
     * 
     * @param billId 账单管理主键
     * @return 结果
     */
    @Override
    public int deleteVetBillByBillId(Long billId)
    {
        return vetBillMapper.deleteVetBillByBillId(billId);
    }

    /**
     * 查询累计未支付账单列表
     * 
     * @return 累计未支付账单集合
     */
    @Override
    public List<VetBill> selectUnpaidBillList()
    {
        return vetBillMapper.selectUnpaidBillList();
    }

    /**
     * 根据客户ID和时间范围查询账单
     * 
     * @param customerId 客户ID
     * @param billPeriodStart 账单周期开始日期
     * @param billPeriodEnd 账单周期结束日期
     * @return 账单信息
     */
    @Override
    public VetBill selectBillByCustomerAndPeriod(Long customerId, Date billPeriodStart, Date billPeriodEnd)
    {
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("billPeriodStart", billPeriodStart);
        params.put("billPeriodEnd", billPeriodEnd);
        return vetBillMapper.selectBillByCustomerAndPeriod(params);
    }

    /**
     * 生成账单编号
     * 
     * @return 账单编号
     */
    @Override
    public String generateBillNo()
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        // 这里可以根据实际需求实现序号生成逻辑
        String sequence = String.format("%03d", (int)(Math.random() * 1000));
        return "ZD" + dateStr + sequence;
    }

    /**
     * 查询账单统计信息
     * 
     * @return 统计信息
     */
    @Override
    public Map<String, Object> selectBillStatistics()
    {
        return vetBillMapper.selectBillStatistics();
    }

    /**
     * 生成客户账单
     * 
     * @param customerId 客户ID
     * @param billPeriodStart 账单周期开始日期
     * @param billPeriodEnd 账单周期结束日期
     * @return 结果
     */
    @Override
    @Transactional
    public int generateCustomerBill(Long customerId, Date billPeriodStart, Date billPeriodEnd)
    {
        // 检查是否已存在该时间段的账单
        VetBill existingBill = selectBillByCustomerAndPeriod(customerId, billPeriodStart, billPeriodEnd);
        if (existingBill != null) {
            throw new ServiceException("该客户在此时间段已存在账单");
        }
        
        // 查询该时间段内的出货记录
        VetOutbound queryOutbound = new VetOutbound();
        queryOutbound.setCustomerId(customerId);
        // 这里需要在VetOutboundMapper中添加按时间范围查询的方法
        List<VetOutbound> outboundList = vetOutboundMapper.selectVetOutboundList(queryOutbound);
        
        if (outboundList == null || outboundList.isEmpty()) {
            throw new ServiceException("该客户在此时间段内无出货记录");
        }
        
        // 计算账单信息
        BigDecimal totalAmount = BigDecimal.ZERO;
        int transactionCount = 0;
        Date earliestDate = null;
        String customerName = null;
        
        // 过滤符合时间范围的出货记录
        List<VetOutbound> filteredOutboundList = new java.util.ArrayList<>();
        for (VetOutbound outbound : outboundList) {
            // 过滤时间范围
            if (outbound.getOutboundDate().compareTo(billPeriodStart) >= 0 && 
                outbound.getOutboundDate().compareTo(billPeriodEnd) <= 0) {
                totalAmount = totalAmount.add(outbound.getTotalAmount());
                transactionCount++;
                filteredOutboundList.add(outbound);
                
                if (customerName == null) {
                    customerName = outbound.getCustomerName();
                }
                
                if (earliestDate == null || outbound.getOutboundDate().before(earliestDate)) {
                    earliestDate = outbound.getOutboundDate();
                }
            }
        }
        
        // 创建账单
        VetBill newBill = new VetBill();
        newBill.setCustomerId(customerId);
        newBill.setCustomerName(customerName);
        newBill.setBillPeriodStart(billPeriodStart);
        newBill.setBillPeriodEnd(billPeriodEnd);
        newBill.setTotalAmount(totalAmount);
        newBill.setPaidAmount(BigDecimal.ZERO);
        newBill.setUnpaidAmount(totalAmount);
        newBill.setTransactionCount(transactionCount);
        newBill.setPaymentStatus("未支付");
        newBill.setEarliestDebtDate(earliestDate);
        
        // 生成账单编号
        newBill.setBillNo(generateBillNo());
        
        // 插入账单
        int result = insertVetBill(newBill);
        
        // 创建账单明细记录
        if (result > 0 && newBill.getBillId() != null) {
            for (VetOutbound outbound : filteredOutboundList) {
                VetBillDetail billDetail = new VetBillDetail();
                billDetail.setBillId(newBill.getBillId());
                billDetail.setOutboundId(outbound.getOutboundId());
                billDetail.setOutboundOrderNo(outbound.getOutboundOrderNo());
                billDetail.setOutboundDate(outbound.getOutboundDate());
                billDetail.setDrugName(outbound.getDrugName());
                billDetail.setDrugSpecification(outbound.getDrugSpecification());
                billDetail.setQuantity(outbound.getQuantity());
                billDetail.setUnitPrice(outbound.getUnitPrice());
                billDetail.setAmount(outbound.getTotalAmount());
                billDetail.setCreateBy(newBill.getCreateBy());
                billDetail.setCreateTime(DateUtils.getNowDate());
                
                // 插入账单明细
                vetBillDetailMapper.insertVetBillDetail(billDetail);
            }
        }
        
        return result;
    }

    /**
     * 更新账单支付状态
     * 
     * @param billId 账单ID
     * @param paidAmount 支付金额
     * @return 结果
     */
    @Override
    @Transactional
    public int updatePaymentStatus(Long billId, BigDecimal paidAmount)
    {
        VetBill bill = selectVetBillByBillId(billId);
        if (bill == null) {
            throw new ServiceException("账单不存在");
        }
        
        // 更新已付金额
        BigDecimal newPaidAmount = bill.getPaidAmount().add(paidAmount);
        bill.setPaidAmount(newPaidAmount);
        bill.setUnpaidAmount(bill.getTotalAmount().subtract(newPaidAmount));
        
        // 更新支付状态
        updatePaymentStatusByAmount(bill);
        
        return updateVetBill(bill);
    }

    /**
     * 根据金额更新支付状态
     * 
     * @param vetBill 账单信息
     */
    private void updatePaymentStatusByAmount(VetBill vetBill)
    {
        if (vetBill.getUnpaidAmount().compareTo(BigDecimal.ZERO) == 0) {
            vetBill.setPaymentStatus("已支付");
        } else if (vetBill.getPaidAmount().compareTo(BigDecimal.ZERO) > 0) {
            vetBill.setPaymentStatus("部分支付");
        } else {
            // 检查是否逾期
            if (vetBill.getDueDate() != null && new Date().after(vetBill.getDueDate())) {
                vetBill.setPaymentStatus("已逾期");
            } else {
                vetBill.setPaymentStatus("未支付");
            }
        }
    }
}